﻿using System;
using System.Messaging;
using System.Transactions;

namespace NsbMonitorClientService.QueueManager
{
    public class BasicQueueMover : IMoveMessageFromQueueToQueue, ICopyMessageFromQueueToQueue
    {
        private delegate Message ReadMessage(MessageQueue messageQueue);

        public bool MoveMessageFromQueueToQueue(string sourceQueueFullPath, string messageId, string destinationQueueFullPath)
        {
            ReadMessage readMessage = (messageQueue) => messageQueue.ReceiveById(messageId, TimeSpan.FromSeconds(5), MessageQueueTransactionType.Automatic);

            return FromQueueToQueue(sourceQueueFullPath, destinationQueueFullPath, readMessage);
        }

        public bool CopyMessageFromQueueToQueue(string sourceQueueFullPath, string messageId, string destinationQueueFullPath)
        {
            ReadMessage readMessage = (messageQueue) => messageQueue.PeekById(messageId, TimeSpan.FromSeconds(5));

            return FromQueueToQueue(sourceQueueFullPath, destinationQueueFullPath, readMessage);
        }

        private bool FromQueueToQueue(string sourceQueueFullPath, string destinationQueueFullPath, ReadMessage readMessage)
        {
            if (!MessageQueue.Exists(sourceQueueFullPath))
            {
                throw new ArgumentException("cannot find queue: " + sourceQueueFullPath);
            }
            if (!MessageQueue.Exists(destinationQueueFullPath))
            {
                throw new ArgumentException("cannot find queue: " + destinationQueueFullPath);
            }
          
            try
            {
                using (var scope = new TransactionScope())
                {
                    using (var sourceQueue = new MessageQueue(sourceQueueFullPath))
                    {
                        var m = readMessage(sourceQueue);

                        using (var destinationQueue = new MessageQueue(destinationQueueFullPath))
                        {
                            destinationQueue.Send(m, MessageQueueTransactionType.Automatic);
                        }

                    }
                    scope.Complete();
                }
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
                return false;
            }

            return true;
        }
    }
}